home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmcd-1.4 / libdi.d / vu_pion.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  9.7 KB  |  437 lines

  1. /*
  2.  *   libdi - CD Audio Player Device Interface Library
  3.  *
  4.  *   Copyright (C) 1995  Ti Kan
  5.  *   E-mail: ti@amb.org
  6.  *
  7.  *   This program is free software; you can redistribute it and/or modify
  8.  *   it under the terms of the GNU General Public License as published by
  9.  *   the Free Software Foundation; either version 2 of the License, or
  10.  *   (at your option) any later version.
  11.  *
  12.  *   This program is distributed in the hope that it will be useful,
  13.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *   GNU General Public License for more details.
  16.  *
  17.  *   You should have received a copy of the GNU General Public License
  18.  *   along with this program; if not, write to the Free Software
  19.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  *   The name "Pioneer" is a trademark of Pioneer Corporation, and is
  22.  *   used here for identification purposes only.  This software and its
  23.  *   author are not affiliated in any way with Pioneer.
  24.  *
  25.  */
  26. #ifndef LINT
  27. static char *_vu_pion_c_ident_ = "@(#)vu_pion.c    5.4 94/12/28";
  28. #endif
  29.  
  30. #include "common.d/appenv.h"
  31. #include "common.d/util.h"
  32. #include "libdi.d/libdi.h"
  33. #include "libdi.d/scsipt.h"
  34.  
  35. #ifdef VENDOR_PIONEER
  36.  
  37. extern appdata_t    app_data;
  38. extern vu_tbl_t        scsipt_vutbl[];
  39.  
  40. /*
  41.  * pion_playaudio
  42.  *    Play audio function: send vendor-unique play audio command
  43.  *    to the drive.
  44.  *
  45.  * Args:
  46.  *    addr_fmt - Flags indicating which address formats are passed in
  47.  *    If ADDR_BLK, then:
  48.  *        start_addr - The logical block starting address
  49.  *        end_addr - The logical block ending address
  50.  *    If ADD_MSF, then:
  51.  *        start_msf - Pointer to the starting MSF address structure
  52.  *        end_msf - Pointer to the ending MSF address structure
  53.  *    If ADDR_TRKIDX, then:
  54.  *        trk - The starting track number
  55.  *        idx - The starting index number
  56.  *    If ADDR_OPTEND, then the ending address, if specified, can be
  57.  *    ignored if possible.
  58.  *
  59.  * Return:
  60.  *    TRUE - success
  61.  *    FALSE - failure
  62.  */
  63. /*ARGSUSED*/
  64. bool_t
  65. pion_playaudio(
  66.     byte_t        addr_fmt,
  67.     word32_t    start_addr,
  68.     word32_t    end_addr,
  69.     msf_t        *start_msf,
  70.     msf_t        *end_msf,
  71.     byte_t        trk,
  72.     byte_t        idx
  73. )
  74. {
  75.     bool_t        ret = FALSE;
  76.     word32_t    addr = 0;
  77.     paudio_arg_t    *p;
  78.  
  79.     p = (paudio_arg_t *) &addr;
  80.  
  81.     if (!ret && addr_fmt & ADDR_MSF) {
  82.         /* Position laser head at desired location
  83.          * and start play.
  84.          */
  85.         p->addr_min = (byte_t) ltobcd(start_msf->min);
  86.         p->addr_sec = (byte_t) ltobcd(start_msf->sec);
  87.         p->addr_frame = (byte_t) ltobcd(start_msf->frame);
  88.  
  89.         ret = pthru_send(
  90.             OP_VP_AUDSRCH,
  91.             addr, NULL, 0, 0, 0,
  92.             0x19, 0x1 << 6, READ_OP, TRUE
  93.         );
  94.  
  95.         if (ret && !(addr_fmt & ADDR_OPTEND)) {
  96.             /* Specify end location and start play */
  97.             p->addr_min = (byte_t) ltobcd(end_msf->min);
  98.             p->addr_sec = (byte_t) ltobcd(end_msf->sec);
  99.             p->addr_frame = (byte_t) ltobcd(end_msf->frame);
  100.  
  101.             ret = pthru_send(
  102.                 OP_VP_AUDPLAY,
  103.                 addr, NULL, 0, 0, 0,
  104.                 0x19, 0x1 << 6, READ_OP, TRUE
  105.             );
  106.         }
  107.     }
  108.  
  109.     if (!ret && addr_fmt & ADDR_BLK) {
  110.         /* Position laser head at desired location
  111.          * and start play.
  112.          */
  113.         p->addr_logical = start_addr;
  114.  
  115.         ret = pthru_send(
  116.             OP_VP_AUDSRCH,
  117.             addr, NULL, 0, 0, 0,
  118.             0x19, 0x0, READ_OP, TRUE
  119.         );
  120.  
  121.         if (ret && !(addr_fmt & ADDR_OPTEND)) {
  122.             /* Specify end location and start play */
  123.             p->addr_logical = end_addr;
  124.  
  125.             ret = pthru_send(
  126.                 OP_VP_AUDPLAY,
  127.                 addr, NULL, 0, 0, 0,
  128.                 0x19, 0x0, READ_OP, TRUE
  129.             );
  130.         }
  131.     }
  132.  
  133.     return (ret);
  134. }
  135.  
  136.  
  137. /*
  138.  * pion_pause_resume
  139.  *    Pause/resume function: send vendor-unique commands to implement
  140.  *    the pause and resume capability.
  141.  *
  142.  * Args:
  143.  *    resume - TRUE: resume, FALSE: pause
  144.  *
  145.  * Return:
  146.  *    TRUE - success
  147.  *    FALSE - failure
  148.  */
  149. bool_t
  150. pion_pause_resume(bool_t resume)
  151. {
  152.     if (resume) {
  153.         return (
  154.             pthru_send(
  155.                 OP_VP_PAUSE, 0, NULL, 0, 0, 0,
  156.                 0x0, 0, READ_OP, TRUE
  157.             )
  158.         );
  159.     }
  160.     else {
  161.         return (
  162.             pthru_send(
  163.                 OP_VP_PAUSE, 0, NULL, 0, 0, 0,
  164.                 0x1 << 4, 0, READ_OP, TRUE
  165.             )
  166.         );
  167.     }
  168. }
  169.  
  170.  
  171. /*
  172.  * pion_get_playstatus
  173.  *    Send vendor-unique command to obtain current audio playback
  174.  *    status.
  175.  *
  176.  * Args:
  177.  *    s - Pointer to the curstat_t structure
  178.  *    audio_status - Address where a current status code (SCSI-2
  179.  *               style) is to be returned.
  180.  *
  181.  * Return:
  182.  *    TRUE - success
  183.  *    FALSE - failure
  184.  */
  185. bool_t
  186. pion_get_playstatus(curstat_t *s, byte_t *audio_status)
  187. {
  188.     int            i,
  189.                 trkno,
  190.                 idxno;
  191.     byte_t            buf[sizeof(psubq_data_t)];
  192.     bool_t            stopped;
  193.     paudstat_data_t        *a;
  194.     psubq_data_t        *d;
  195.  
  196.  
  197.     memset(buf, 0, sizeof(buf));
  198.  
  199.     /* Send Pioneer Read Audio Status command */
  200.     if (!pthru_send(OP_VP_AUDSTAT, 0, buf, SZ_VP_AUDSTAT,
  201.             0, SZ_VP_AUDSTAT, 0, 0, READ_OP, TRUE))
  202.         return FALSE;
  203.  
  204.     DBGDUMP("pion: Read Audio Status data bytes", buf, SZ_VP_AUDSTAT);
  205.  
  206.     a = (paudstat_data_t *)(void *) buf;
  207.  
  208.     stopped = FALSE;
  209.  
  210.     /* Translate Pioneer audio status to SCSI-2 audio status */
  211.     switch (a->status) {
  212.     case PAUD_PLAYING:
  213.     case PAUD_MUTEPLAY:
  214.         *audio_status = AUDIO_PLAYING;
  215.         break;
  216.  
  217.     case PAUD_PAUSED:
  218.         *audio_status = AUDIO_PAUSED;
  219.         break;
  220.  
  221.     case PAUD_COMPLETED:
  222.         *audio_status = AUDIO_COMPLETED;
  223.         stopped = TRUE;
  224.         break;
  225.  
  226.     case PAUD_ERROR:
  227.         *audio_status = AUDIO_FAILED;
  228.         stopped = TRUE;
  229.         break;
  230.  
  231.     case PAUD_NOSTATUS:
  232.         *audio_status = AUDIO_NOSTATUS;
  233.         stopped = TRUE;
  234.         break;
  235.     }
  236.  
  237.     if (stopped) {
  238.         s->cur_tot_min = (byte_t) bcdtol(a->abs_min);
  239.         s->cur_tot_sec = (byte_t) bcdtol(a->abs_sec);
  240.         s->cur_tot_frame = (byte_t) bcdtol(a->abs_frame);
  241.  
  242.         if ((i = curtrk_pos(s)) >= 0)
  243.             s->trkinfo[i].type =
  244.                 (a->trktype == 0) ? TYP_AUDIO : TYP_DATA;
  245.  
  246.         return TRUE;
  247.     }
  248.  
  249.     memset(buf, 0, sizeof(buf));
  250.  
  251.     /* Send Pioneer Read Subcode Q command */
  252.     if (!pthru_send(OP_VP_RDSUBQ, 0, buf, SZ_VP_RDSUBQ,
  253.             0, SZ_VP_RDSUBQ, 0, 0, READ_OP, TRUE))
  254.         return FALSE;
  255.  
  256.     DBGDUMP("pion: Read Subcode Q data bytes", buf, SZ_VP_RDSUBQ);
  257.  
  258.     d = (psubq_data_t *)(void *) buf;
  259.  
  260.     trkno = bcdtol((word32_t) d->trkno);
  261.     if (s->cur_trk != trkno) {
  262.         s->cur_trk = trkno;
  263.         dpy_track(s);
  264.     }
  265.  
  266.     idxno = bcdtol((word32_t) d->idxno);
  267.     if (s->cur_idx != idxno) {
  268.         s->cur_idx = idxno;
  269.         s->sav_iaddr = s->cur_tot_addr;
  270.         dpy_index(s);
  271.     }
  272.  
  273.     if ((i = curtrk_pos(s)) >= 0)
  274.         s->trkinfo[i].type =
  275.             (d->trktype == 0) ? TYP_AUDIO : TYP_DATA;
  276.  
  277.     s->cur_tot_min = (byte_t) bcdtol(d->abs_min);
  278.     s->cur_tot_sec = (byte_t) bcdtol(d->abs_sec);
  279.     s->cur_tot_frame = (byte_t) bcdtol(d->abs_frame);
  280.     s->cur_trk_min = (byte_t) bcdtol(d->rel_min);
  281.     s->cur_trk_sec = (byte_t) bcdtol(d->rel_sec);
  282.     s->cur_trk_frame = (byte_t) bcdtol(d->rel_frame);
  283.     msftoblk(
  284.         s->cur_tot_min, s->cur_tot_sec, s->cur_tot_frame,
  285.         &s->cur_tot_addr, MSF_OFFSET(s)
  286.     );
  287.     msftoblk(
  288.         s->cur_trk_min, s->cur_trk_sec, s->cur_trk_frame,
  289.         &s->cur_trk_addr, 0
  290.     );
  291.  
  292.     return TRUE;
  293. }
  294.  
  295.  
  296. /*
  297.  * pion_get_toc
  298.  *    Send vendor-unique command to obtain the disc table-of-contents
  299.  *
  300.  * Args:
  301.  *    s - Pointer to the curstat_t structure, which contains the TOC
  302.  *        table to be updated.
  303.  *
  304.  * Return:
  305.  *    TRUE - success
  306.  *    FALSE - failure
  307.  */
  308. bool_t
  309. pion_get_toc(curstat_t *s)
  310. {
  311.     int        i,
  312.             j;
  313.     byte_t        buf[SZ_VP_RDTOC];
  314.     pinfo_00_t    *t0;
  315.     pinfo_01_t    *t1;
  316.     pinfo_02_t    *t2;
  317.  
  318.  
  319.     memset(buf, 0, sizeof(buf));
  320.  
  321.     /* Find number of tracks */
  322.     if (!pthru_send(OP_VP_RDTOC, 0, buf, SZ_VP_RDTOC,
  323.             0, SZ_VP_RDTOC, 0, 0, READ_OP, TRUE))
  324.         return FALSE;
  325.  
  326.     DBGDUMP("pion: Read TOC data bytes", buf, SZ_VP_RDTOC);
  327.  
  328.     t0 = (pinfo_00_t *) buf;
  329.     s->first_trk = (byte_t) bcdtol(t0->first_trk);
  330.     s->last_trk = (byte_t) bcdtol(t0->last_trk);
  331.  
  332.     /* Get the starting position of each track */
  333.     for (i = 0, j = (int) s->first_trk; j <= (int) s->last_trk; i++, j++) {
  334.         memset(buf, 0, sizeof(buf));
  335.  
  336.         if (!pthru_send(OP_VP_RDTOC, ltobcd(j),
  337.                 buf, SZ_VP_RDTOC, 0, SZ_VP_RDTOC, 0,
  338.                 0x2 << 6, READ_OP, TRUE))
  339.             return FALSE;
  340.  
  341.         DBGDUMP("pion: Read TOC data bytes", buf, SZ_VP_RDTOC);
  342.  
  343.         t2 = (pinfo_02_t *)(void *) buf;
  344.  
  345.         s->trkinfo[i].trkno = j;
  346.         s->trkinfo[i].min = (byte_t) bcdtol(t2->min);
  347.         s->trkinfo[i].sec = (byte_t) bcdtol(t2->sec);
  348.         s->trkinfo[i].frame = (byte_t) bcdtol(t2->frame);
  349.         msftoblk(
  350.             s->trkinfo[i].min,
  351.             s->trkinfo[i].sec,
  352.             s->trkinfo[i].frame,
  353.             &s->trkinfo[i].addr,
  354.             MSF_OFFSET(s)
  355.         );
  356.     }
  357.     s->tot_trks = (byte_t) i;
  358.  
  359.     memset(buf, 0, sizeof(buf));
  360.  
  361.     /* Get the lead out track position */
  362.     if (!pthru_send(OP_VP_RDTOC, 0,
  363.             buf, SZ_VP_RDTOC, 0, SZ_VP_RDTOC, 0,
  364.             0x1 << 6, READ_OP, TRUE))
  365.         return FALSE;
  366.  
  367.     DBGDUMP("pion: Read TOC data bytes", buf, SZ_VP_RDTOC);
  368.  
  369.     t1 = (pinfo_01_t *) buf;
  370.  
  371.     s->trkinfo[i].trkno = LEAD_OUT_TRACK;
  372.     s->tot_min = s->trkinfo[i].min = (byte_t) bcdtol(t1->min);
  373.     s->tot_sec = s->trkinfo[i].sec = (byte_t) bcdtol(t1->sec);
  374.     s->tot_frame = s->trkinfo[i].frame = (byte_t) bcdtol(t1->frame);
  375.     msftoblk(
  376.         s->trkinfo[i].min,
  377.         s->trkinfo[i].sec,
  378.         s->trkinfo[i].frame,
  379.         &s->trkinfo[i].addr,
  380.         MSF_OFFSET(s)
  381.     );
  382.     s->tot_addr = s->trkinfo[i].addr;
  383.  
  384.     return TRUE;
  385. }
  386.  
  387.  
  388. /*
  389.  * pion_eject
  390.  *    Send vendor-unique command to eject the caddy
  391.  *
  392.  * Args:
  393.  *    Nothing.
  394.  *
  395.  * Return:
  396.  *    TRUE - success
  397.  *    FALSE - failure
  398.  */
  399. bool_t
  400. pion_eject(void)
  401. {
  402.     return (pthru_send(OP_VP_EJECT, 0, NULL, 0, 0, 0, 1, 0, READ_OP, TRUE));
  403. }
  404.  
  405.  
  406. /*
  407.  * pion_init
  408.  *    Initialize the vendor-unique support module
  409.  *
  410.  * Args:
  411.  *    Nothing.
  412.  *
  413.  * Return:
  414.  *    Nothing.
  415.  */
  416. void
  417. pion_init(void)
  418. {
  419.     /* Register vendor_unique module entry points */
  420.     scsipt_vutbl[VENDOR_PIONEER].vendor = "Pioneer";
  421.     scsipt_vutbl[VENDOR_PIONEER].playaudio = pion_playaudio;
  422.     scsipt_vutbl[VENDOR_PIONEER].pause_resume = pion_pause_resume;
  423.     scsipt_vutbl[VENDOR_PIONEER].start_stop = NULL;
  424.     scsipt_vutbl[VENDOR_PIONEER].get_playstatus = pion_get_playstatus;
  425.     scsipt_vutbl[VENDOR_PIONEER].volume = NULL;
  426.     scsipt_vutbl[VENDOR_PIONEER].route = NULL;
  427.     scsipt_vutbl[VENDOR_PIONEER].mute = NULL;
  428.     scsipt_vutbl[VENDOR_PIONEER].get_toc = pion_get_toc;
  429.     scsipt_vutbl[VENDOR_PIONEER].eject = pion_eject;
  430.     scsipt_vutbl[VENDOR_PIONEER].start = NULL;
  431.     scsipt_vutbl[VENDOR_PIONEER].halt = NULL;
  432. }
  433.  
  434.  
  435. #endif    /* VENDOR_PIONEER */
  436.  
  437.